package com.crazy.base.common.utils.servicelocate;

import lombok.Setter;

import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

public class ServiceLocator {

    @Setter
    private static ServiceRegistry registry;

    private ServiceLocator() {}

    public static <T> T service(Class<T> clazz) {
        assertRegistryNotNull();
        return Optional.ofNullable(registry.getService(clazz))
                .orElseThrow(illegalArgumentException(clazz.getName()));
    }

    public static <T> T service(String serviceName, Class<T> clazz) {
        assertRegistryNotNull();
        return Optional.ofNullable(registry.getService(serviceName, clazz))
                .orElseThrow(illegalArgumentException(serviceName, clazz.getName()));
    }

    private static void assertRegistryNotNull() {
        if (Objects.isNull(registry)) {
            throw new IllegalStateException("Please initiate registry before using service method.");
        }
    }

    private static Supplier<IllegalArgumentException> illegalArgumentException(String typeName) {
        return () -> new IllegalArgumentException(String.format("%s could not be found in registry.", typeName));
    }

    private static Supplier<IllegalArgumentException> illegalArgumentException(String beanName, String typeName) {
        return () -> new IllegalArgumentException(String.format("%s[type:%s] could not be found in registry.", beanName, typeName));
    }

}
